package avicit.bdp.dcs.datasource.service.ds;

import avicit.bdp.common.datasource.BaseDataSource;
import avicit.bdp.common.datasource.HiveDataSource;
import avicit.bdp.common.service.dto.DataSourceDTO;
import avicit.bdp.common.utils.database.DBUtils;
import avicit.bdp.common.utils.enums.JobType;
import avicit.bdp.dcs.utils.JdbcConstants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @金航数码科技有限责任公司
 * @作者：zhuhy
 * @邮箱：zhuhy@avic-digital.com
 * @创建时间： 2020-11-12
 * @类说明：BaseDS
 * @修改记录：
 * @注意事项：为了避免繁复，此处使用DS作为DataSource的简写
 * @功能：数据源获取基类
 */
public abstract class BaseDS {

    private static final Logger logger = LoggerFactory.getLogger(BaseDS.class);

    /**
     * 获取数据源的类型
     *
     * @return type
     */
    public abstract String type();

    /**
     * 判断是否支持结构化采集
     *
     * @return
     */
    public abstract boolean isSupportStructCollection();

    /**
     * 判断是否支持半结构化采集
     *
     * @return
     */
    public abstract boolean isSupportSemiStructCollection();

    /**
     * 判断是否支持流式采集
     *
     * @return
     */
    public abstract boolean isSupportStreamCollection();

    /**
     * 判断是否支持API采集
     *
     * @return
     */
    public abstract boolean isSupportAPICollection();

    /**
     * 判断是否需要用户名和密码
     *
     * @return
     */
    public abstract boolean needUserAndPassword();

    /**
     * 获取数据源名称
     *
     * @return datasource
     */
    public abstract String getDatasource();

    /**
     * 获取数据源驱动类
     *
     * @return jdbcDriverClass
     */
    public abstract String getJdbcDriverClass();

    /**
     * 判断是否支持指定的jobType
     *
     * @param jobType
     * @return
     */
    public boolean isSupportJobType(JobType jobType) {
        switch (jobType) {
            case TRANSFER:
            case SYNC:
                if (isSupportStructCollection()) {
                    return true;
                }
                break;
            case SEMISTRUCTURE:
                if (isSupportSemiStructCollection()) {
                    return true;
                }
                break;
            case STREAM:
                if (isSupportStreamCollection()) {
                    return true;
                }
                break;
            case API_HTTP:
                if (isSupportAPICollection()) {
                    return true;
                }
                break;
            default:
                logger.error("错误的jobType:{}", jobType);
                break;
        }

        return false;
    }

    /**
     * 判断数据源的参数是否合法
     *
     * @param dataSourceDTO
     * @return
     */
    public boolean checkParams(DataSourceDTO dataSourceDTO) {
        if (!checkJdbcUrl(dataSourceDTO)) {
            return false;
        }

        // 判断是否需要检查用户名和密码
        if (needUserAndPassword()) {
            return checkUserAndPassword(dataSourceDTO);
        }

        return true;
    }

    /**
     * 判断数据源的jdbcUrl是否合法
     *
     * @param dataSourceDTO
     * @return
     */
    private boolean checkJdbcUrl(DataSourceDTO dataSourceDTO) {
        BaseDataSource baseDataSource = DBUtils.getBaseDataSource(dataSourceDTO);
        if (StringUtils.isEmpty(baseDataSource.getJdbcUrl())) {
            logger.warn("jdbcUrl is blank");
            return false;
        }

        return true;
    }

    /**
     * 判断数据源的用户名和密码是否合法
     *
     * @param dataSourceDTO
     * @return
     */
    private boolean checkUserAndPassword(DataSourceDTO dataSourceDTO) {
        BaseDataSource baseDataSource = DBUtils.getBaseDataSource(dataSourceDTO);

        // hive开启kerberos认证，则不验证账号密码
        if(JdbcConstants.HIVE.equals(dataSourceDTO.getDatasourceType())){
            HiveDataSource hiveDataSource = (HiveDataSource) baseDataSource;
            if(hiveDataSource.getKerberos() == 1){
                return true;
            }
        }

        if (StringUtils.isEmpty(baseDataSource.getUser())) {
            logger.warn("jdbcUsername is blank");
            return false;
        }

        if (StringUtils.isEmpty(baseDataSource.getPassword())) {
            logger.warn("jdbcPassword is blank");
            return false;
        }

        return true;
    }

}
